﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEditor.VersionControl;
using UnityEngine;
using System.Collections;

/// <summary>
/// Author:苟谆
/// 针对不同平台来更改Texture的TextureFormat
/// 工具路径：Coser/Tools/Change Textures
/// 
/// </summary>
public class ChangeTextureSettings : EditorWindow
{
	public List<Texture2D> Texs;

	private Dictionary<string, string> pathes = new Dictionary<string, string>();

	private TextAsset configAsset;

	private Vector2 mScroll;

	private string configFilePath = "Assets/_Gate/Editor/TexturesCompress/pathes.txt";



	[MenuItem("Coser/Tools/Change Textures")]
	public static void InitWindow()
	{
		EditorWindow.GetWindow<ChangeTextureSettings>();

	}

	public ChangeTextureSettings()
	{
		Texs = new List<Texture2D>();
		configAsset = AssetDatabase.LoadAssetAtPath(configFilePath, typeof(TextAsset)) as TextAsset;
		if (!configAsset)
		{
			Debug.LogError("config File has not been found...pls check it");
		}
	}

	private string pathshow;
	private void OnGUI()
	{
		if (Texs.Count == 0)
		{
			if (configAsset)
			{
				LoadConfig(configAsset.text);
				foreach (KeyValuePair<string, string> t in pathes)
				{
					Debug.Log(t.Value);
					Texs.Add(AssetDatabase.LoadAssetAtPath(t.Value, typeof(Texture2D)) as Texture2D);
				}
			}
		}

		if (GUILayout.Button("Find All the texture..."))
		{
			FindAllTexture();
		}

	    if (GUILayout.Button("Find All Need Texture"))
	    {
	        FindAllNeedTexture();
	    }
		#region Change for any platform texture
		if (GUILayout.Button("Change for IOS"))
		{
			ChangeForIOS();

		}

		if (GUILayout.Button("Change for Andorid"))
		{
			ChangeForAndroid();

		}

		if (GUILayout.Button("Change jpg for ios"))
		{
			ChangeJPGFormat(TextureImporterFormat.PVRTC_RGB4, 100);
		}

		if (GUILayout.Button("Change jpg for android"))
		{
			ChangeJPGFormat(TextureImporterFormat.ETC_RGB4, 100);
		}

		//if (GUILayout.Button("Heavy png for android"))
		//{
		//	ChangeHeavyPNGFormat(TextureImporterFormat.PVRTC_RGBA4);
		//}

		if (GUILayout.Button("Heavy PNG for ios"))
		{
			ChangeHeavyPNGFormat(TextureImporterFormat.PVRTC_RGBA4);
		}

		if (GUILayout.Button("Heavy PNG for Qualcomm"))
		{
			ChangeHeavyPNGFormat(TextureImporterFormat.ATC_RGBA8);
		}

		if (GUILayout.Button("Heavy PNG for PowerVR"))
		{
			ChangeHeavyPNGFormat(TextureImporterFormat.PVRTC_RGBA4);
		}

		if (GUILayout.Button("PNG8 texture comrpess"))
		{
			ChangePNG8Format(TextureImporterFormat.Alpha8);
		}

		if (GUILayout.Button("RGB texture Compress"))
		{

		}

		GUI.color = Color.yellow;
		if (GUILayout.Button("NGUI Atlas Texture Compresss"))
		{
			CompresssNGUIAtlas(TextureImporterFormat.ARGB16);
		}

		GUI.color = Color.cyan;
		if (GUILayout.Button("NGUI Atlas Texture TrueColor"))
		{
			CompresssNGUIAtlas();
		}
		GUI.color = Color.red;
		if (GUILayout.Button("ONEKEY COMPRESS!"))
		{
			throw new NotImplementedException("you did not do this...");
		}
		GUI.color = Color.white;
		#endregion

		EditorGUILayout.BeginHorizontal();

		configAsset = EditorGUILayout.ObjectField(configAsset, typeof(TextAsset), false) as TextAsset;
		if (GUILayout.Button("Save to Config File"))
		{
			SaveToFile();
		}

		EditorGUILayout.EndHorizontal();
		EditorGUILayout.LabelField("All Texture count:" + Texs.Count.ToString());
		if (configAsset)
		{
			pathshow = AssetDatabase.GetAssetPath(configAsset);
			EditorGUILayout.LabelField(pathshow);
		}

		mScroll = EditorGUILayout.BeginScrollView(mScroll);


		for (int i = 0; i < Texs.Count; i++)
		{
			var tex = Texs[i];
			if (tex)
			{
				EditorGUILayout.BeginHorizontal();
				if (GUILayout.Button(tex.name, GUILayout.Width(150)))
				{
					DeleteTexture(tex);
					//Texs[i] = EditorGUILayout.ObjectField(Texs[i], typeof(Texture2D), false) as Texture2D;
				}
				else
				{
					Texs[i] = EditorGUILayout.ObjectField(Texs[i], typeof(Texture2D), false) as Texture2D;
				}
				EditorGUILayout.EndHorizontal();
			}

		}
		EditorGUILayout.EndScrollView();


	}

	private void FindAllTexture()
	{
		Texs = new List<Texture2D>();


		var texGuids = AssetDatabase.FindAssets("t:Texture2D");
		//var texs = Selection.GetFiltered(typeof (Texture2D), SelectionMode.DeepAssets);
		Debug.Log(texGuids.Count());
		foreach (string texGuid in texGuids)
		{
			var assetpath = AssetDatabase.GUIDToAssetPath((texGuid));

			//	Debug.Log(texture2D.name +" path:" + assetpath);
			if (!string.IsNullOrEmpty(assetpath))
			{
				var tex = AssetDatabase.LoadAssetAtPath(assetpath, typeof(Texture2D)) as Texture2D;
				//TODO:filter condition
                if (tex != null && tex.width >= 128 && tex.height >= 128 && !assetpath.Contains("StreamingAssets") && !assetpath.ToLower().Contains("plugins"))
				{
					Texs.Add(tex);
				}
			}
		}
	}


    private void FindAllNeedTexture()
    {
        Texs = new List<Texture2D>();


        var texGuids = AssetDatabase.FindAssets("t:Texture2D");
        //var texs = Selection.GetFiltered(typeof (Texture2D), SelectionMode.DeepAssets);
        Debug.Log(texGuids.Count());
        foreach (string texGuid in texGuids)
        {
            var assetpath = AssetDatabase.GUIDToAssetPath((texGuid));

            //	Debug.Log(texture2D.name +" path:" + assetpath);
            if (!string.IsNullOrEmpty(assetpath))
            {
                var tex = AssetDatabase.LoadAssetAtPath(assetpath, typeof(Texture2D)) as Texture2D;
                ////TODO:filter condition
                //if (tex != null && tex.width >= 128 && tex.height >= 128)
                //{
                //    Texs.Add(tex);
                //}

                var texImporter = AssetImporter.GetAtPath(assetpath) as TextureImporter;
                if (texImporter.textureFormat == TextureImporterFormat.PVRTC_RGB4 || texImporter.textureFormat == TextureImporterFormat.PVRTC_RGBA4 &&(tex.width != tex.height))
                {
                    Debug.Log("Add:" + assetpath);
                    Texs.Add(tex);
                }
            }
        }
    }

	private void CompresssNGUIAtlas(TextureImporterFormat format = TextureImporterFormat.ARGB32)
	{
		FindAllAtlasTexture();

		for (int index = 0; index < Texs.Count; index++)
		{
			var texture2D = Texs[index];
			var path = AssetDatabase.GetAssetPath(texture2D);
			SetupImporter(format, 100, path, texture2D, TextureImporterNPOTScale.None);
			EditorUtility.DisplayCancelableProgressBar("Changing~~", path, index / (float)Texs.Count);
		}
		EditorUtility.ClearProgressBar();
	}

	private void FindAllAtlasTexture()
	{
        //Texs = new List<Texture2D>();
        //var goGuids = AssetDatabase.FindAssets("t:GameObject");

        //foreach (string goGuid in goGuids)
        //{
        //    var assetpath = AssetDatabase.GUIDToAssetPath((goGuid));

        //    //	Debug.Log(texture2D.name +" path:" + assetpath);
        //    if (!string.IsNullOrEmpty(assetpath))
        //    {
        //        var atlas = AssetDatabase.LoadAssetAtPath(assetpath, typeof (UIAtlas)) as UIAtlas;
        //        if (atlas)
        //        {
        //            var tex = atlas.spriteMaterial.GetTexture("_MainTex") as Texture2D;
        //            Texs.Add(tex);
        //        }
        //    }
        //}
        //Debug.Log("Found out Atlas Texture Count:" + Texs.Count);
	}

	#region Change logical methods

	private void ChangeForIOS()
	{
		ChangeFormat(TextureImporterFormat.PVRTC_RGBA4);
		ChangeJPGFormat(TextureImporterFormat.PVRTC_RGB4);
	}

	private void ChangeForAndroid()
	{
		ChangeFormat(TextureImporterFormat.PVRTC_RGBA4);
		ChangeJPGFormat(TextureImporterFormat.ETC_RGB4);
	}

	#endregion

	#region private logical

	private string[] LoadConfig(string path)
	{
		string[] pairs = path.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
		foreach (var pair in pairs)
		{
			var key = pair.Split('/').Last();
			if (!pathes.ContainsKey(key))
			{
				pathes.Add(key, pair);
			}
		}
		return pairs;
	}

	private void ChangeFormat(TextureImporterFormat format, int quality = 100)
	{
		for (int index = 0; index < Texs.Count; index++)
		{
			var texture2D = Texs[index];
			var path = AssetDatabase.GetAssetPath(texture2D);

			EditorUtility.DisplayProgressBar("Changing~~", path, index / ((float)Texs.Count));
			var extension = Path.GetExtension(path);
			if (extension != null && (extension.ToLower() != ".jpg" && Mathf.IsPowerOfTwo(texture2D.width) && Mathf.IsPowerOfTwo(texture2D.height) && texture2D.width == texture2D.height))
			{
				SetupImporter(format, quality, path, texture2D, TextureImporterNPOTScale.None);
			}
		}
		EditorUtility.ClearProgressBar();
	}


	private void ChangeJPGFormat(TextureImporterFormat format, int quality = 100)
	{
		var jpgPics = new List<Texture2D>();
		foreach (var texture2D in Texs)
		{
			var path = AssetDatabase.GetAssetPath(texture2D);
			var extension = Path.GetExtension(path);
			if (extension != null && extension.ToLower() == ".jpg" && (texture2D.width >= 128 || texture2D.height >= 128))
			{
				jpgPics.Add(texture2D);
			}
		}

		for (int index = 0; index < jpgPics.Count; index++)
		{
			var texture2D = jpgPics[index];
			var path = AssetDatabase.GetAssetPath(texture2D);
			EditorUtility.DisplayCancelableProgressBar("Changing~~", path, index / (float)jpgPics.Count);
			Debug.Log("TextureFormat切换成功：" + path);
			SetupImporter(format, quality, path, texture2D, TextureImporterNPOTScale.ToLarger);
		}


		EditorUtility.ClearProgressBar();
	}

	private void ChangeHeavyPNGFormat(TextureImporterFormat format, int quality = 100)
	{
		var pngPics = new List<Texture2D>();
		foreach (var texture2D in Texs)
		{
			var path = AssetDatabase.GetAssetPath(texture2D);
			var extension = Path.GetExtension(path);
			if (extension != null && extension.ToLower() == ".png" && (texture2D.width == texture2D.height) && texture2D.width >= 512)
			{
				pngPics.Add(texture2D);
			}
		}

		for (int index = 0; index < pngPics.Count; index++)
		{
			var texture2D = pngPics[index];
			var path = AssetDatabase.GetAssetPath(texture2D);
			EditorUtility.DisplayCancelableProgressBar("Changing~~", path, index / (float)pngPics.Count);
			Debug.Log("TextureFormat切换成功：" + path);
			SetupImporter(format, quality, path, texture2D, TextureImporterNPOTScale.ToLarger);
		}


		EditorUtility.ClearProgressBar();
	}

	private void ChangePNG8Format(TextureImporterFormat alpha8)
	{
		var png8Pics = new List<Texture2D>();
		foreach (var texture2D in Texs)
		{
			var path = AssetDatabase.GetAssetPath(texture2D);
			var extension = Path.GetExtension(path);
			var fileName = Path.GetFileNameWithoutExtension(path);
			if (extension != null && extension.ToLower() == ".jpg" && fileName.ToLower().StartsWith("alpha_"))
			{
				png8Pics.Add(texture2D);
			}
		}

		for (int index = 0; index < png8Pics.Count; index++)
		{
			var texture2D = png8Pics[index];
			var path = AssetDatabase.GetAssetPath(texture2D);
			EditorUtility.DisplayCancelableProgressBar("Changing~~", path, index / (float)png8Pics.Count);
			Debug.Log("TextureFormat切换成功：" + path);
			SetupImporter(alpha8, 100, path, texture2D, TextureImporterNPOTScale.ToLarger);
		}


		EditorUtility.ClearProgressBar();
	}


	public static void SetupImporter(TextureImporterFormat format, int quality, string path, Texture2D texture2D, TextureImporterNPOTScale npot,TextureWrapMode wrap = TextureWrapMode.Clamp)
	{
		var importer = AssetImporter.GetAtPath(path) as TextureImporter;

		if (importer != null)
		{
			Debug.Log(texture2D.name + " quality percent:" + importer.compressionQuality);
			importer.textureType = TextureImporterType.Advanced;
			importer.alphaIsTransparency = false;
			importer.grayscaleToAlpha = false;
			importer.linearTexture = false;
			importer.anisoLevel = 100;
			importer.wrapMode = TextureWrapMode.Clamp;
			importer.npotScale = npot;
			importer.mipmapEnabled = false;
			importer.textureFormat = format;
			importer.compressionQuality = quality;
			importer.filterMode = FilterMode.Trilinear; 
			//importer.spriteImportMode = SpriteImportMode.Single;
			//importer.spritePixelsToUnits = 100;
		}
		AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
	}


	private void DeleteTexture(Texture2D tex)
	{
		Texs.Remove(tex);
		SaveToFile();
	}

	private void SaveToFile()
	{
		pathes = new Dictionary<string, string>();
		foreach (var texture in Texs)
		{
			var path = AssetDatabase.GetAssetPath(texture);
			var key = path.Split('/').Last();
			if (!pathes.ContainsKey(key))
			{
				pathes.Add(key, path);
			}
		}

		using (StreamWriter sw = new StreamWriter(configFilePath, false, Encoding.UTF8))
		{
			foreach (var pathe in pathes.Values)
			{
				sw.WriteLine(pathe);
			}
		}
	}


	#endregion

}
